<?php

namespace App\Core\Traits;

use App\Core\Database\EloquentBuilder;
use App\Core\Database\QueryBuilder;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Support\Facades\Cache;

/**
 * Trait Cacheable
 * @package App\Core\Traits
 */
trait Cacheable
{
    /**
     * Indicates whether the model query from cache.
     *
     * @var boolean
     */
    protected $cacheable = true;

    /*
     *  缓存方式
     * index: 使用数据库主键缓存 支持同步修改删除 默认方式
     * sql: 缓存查询语句的结果 只支持查询操作
     */
    protected $cacheMode = 'index';

    /**
     * 自动缓存关联查询 默认打开
     * 如果查询的主模型开启了缓存，而关联模型没有开启，在进行关联查询的时候，该参数会起作用
     */
    // protected $relationsCacheable = true;

    /**
     * 数据缓存方式，默认存放到redis到string中
     * string: 序列化后保存
     * hash: 使用redis到hash存储
     */
    // protected $cacheDataType = 'string';

    /**
     * 缓存的键名格式
     * 缓存方式为sql时使用sql语句md5后的结果为key
     *
     * @var string
     */
    // protected $cacheKeyFormat = 'TABLE:VALUE';

    /**
     *  缓存过期时间
     *
     * @var int
     */
    // protected $cacheExpire = 3600;

    /**
     * Get a new query builder instance for the connection.
     *
     * @return \App\Core\Database\QueryBuilder
     */
    protected function newBaseQueryBuilder()
    {
        $connection = $this->getConnection();

        return (new QueryBuilder(
            $connection, $connection->getQueryGrammar(), $connection->getPostProcessor(), $this
        ))->setDebug(true);
    }


    /**
     * Rewrite the Eloquent query builder
     *
     * @param  \Illuminate\Database\Query\Builder  $query
     * @return Builder|static
     */
    public function newEloquentBuilder($query)
    {
        return new EloquentBuilder($query);
    }


    public function setMode($mode = 'index')
    {
        $this->cacheMode = $mode;

        return $this;
    }

    public function setCacheKeyFormat($format = 'TABLE:VALUE')
    {
        $this->cacheKeyFormat = $format;

        return $this;
    }

    /**
     * Prevent the model query from cache
     *
     * @return $this
     */
    public function withoutCache()
    {
        $this->cacheable = false;

        return $this;
    }


    /**
     * Prevent the model relations query from cache
     *
     * @return $this
     */
    public function withoutRelaion()
    {
        $this->relationsCacheable = false;

        return $this;
    }

    /**
     * Determine if the model cache is enabled.
     *
     * @return boolean
     */
    public function isCacheable()
    {
        return $this->cacheable;
    }

    /**
     * Determine whether auto cache the model relationships
     *
     * @return boolean
     */
    public function isRelationsCacheable()
    {
        return $this->relationsCacheable ?? true;
    }

    /**
     * Get the model cache key format
     *
     * @return string
     */
    public function getCacheKeyFormat()
    {
        return $this->cacheKeyFormat ?? 'TABLE:VALUE';
    }

    /**
     * Get the model cache save type
     *
     * @return string
     */
    public function getCacheSaveType()
    {
        return $this->cacheDataType ?? 'string';
    }

    /**
     * Get the model cache mode
     *
     * @return string
     */
    public function getCacheMode()
    {
        return $this->cacheMode ?? 'index';
    }

    public function runInSqlMode()
    {
        return $this->getCacheMode() == 'sql';
    }

    public function getExpire()
    {
        return $this->cacheExpire ?? 3600;
    }

    public function setExpire($expire)
    {
        $this->cacheExpire = $expire;

        return $this;
    }

}
